# -*- coding: UTF-8 -*-
import json
import math

def ReadJsonData(historyJson):
    historyList = json.loads(historyJson)
    user_commodity = {}
    for history in historyList:
        userid = history['userid']
        commid = history['commid']
        views = history['views']
        user_commodity.setdefault(userid, {})
        user_commodity[userid][commid] = int(views)
    return user_commodity

def CommoditySimilarity(user_commodity):
    # 建立商品间的相似度
    C = {}  # 存放最终物品相似度矩阵
    N = {}  # 存放每个电影的评分人数
    for userid, commodities in user_commodity.items():
        # 对所有评分数据进行处理
        for i in commodities.keys():
            N.setdefault(i, 0)
            N[i] += 1
            C.setdefault(i, {})
            for j in commodities.keys():
                if i == j:
                    continue
                C[i].setdefault(j, 0)
                C[i][j] += 1
    # 计算最终的物品余弦相似度矩阵
    # W：由矩阵C进化而来
    W = {}
    for i, related_items in C.items():
        W.setdefault(i, {})
        # cij：表示N(u)^N(v)
        for j, cij in related_items.items():
            # 求余弦相似度
            W[i][j] = cij / (math.sqrt(N[i] * N[j]))
    return W

def RecommendCommodities(userid, user_commodity, W, K, N):
    rank = {}  # 存放推荐计算结果
    commidList = []
    action_item = user_commodity[userid]  # 用户1评价过的所有商品
    for commid, views in action_item.items():  # 遍历用户1评价过的所有电影，取得item为user1评分过的电影id
        for j, wj in sorted(W[commid].items(), key=lambda x: x[1], reverse=True)[0:K]:
            if j in action_item.keys():  # 取W物品相似度矩阵中，对应商品的id
                continue
            rank.setdefault(j, 0)
            rank[j] += views * wj  # 综合浏览量给出排列顺序
    return dict(sorted(rank.items(), key=lambda x: x[1], reverse=True)[0:N])  # 排序，并取前N个推荐结果


# K表示取K个相似的用户进行计算
# N表示推荐结果个数
def getRecommendCommodities(userid, historyJson, K, N):
    recommendList = []
    # 加载数据
    user_commodity = ReadJsonData(historyJson)
    # 计算物品相似度
    W = CommoditySimilarity(user_commodity)
    # 计算推荐结果，并取Top-N的推荐结果
    result = RecommendCommodities(userid, user_commodity, W, K, N)
    for i in result.keys():
            recommendList.append(i)
    return json.dumps(recommendList)

